package com.xyht.medicine_management_system.modules.stock.util;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xyht.medicine_management_system.common.commonReturn.CommonCodeEnum;
import com.xyht.medicine_management_system.common.commonReturn.CommonResult;
import com.xyht.medicine_management_system.common.commonReturn.ExceptionCast;
import com.xyht.medicine_management_system.modules.medicine.entity.MmsMedicine;
import com.xyht.medicine_management_system.modules.medicine.mapper.MmsMedicineMapper;
import com.xyht.medicine_management_system.modules.stock.entity.MmsMedicineStock;
import com.xyht.medicine_management_system.modules.stock.entity.MmsMedicineStockLog;
import com.xyht.medicine_management_system.modules.stock.mapper.MmsMedicineStockLogMapper;
import com.xyht.medicine_management_system.modules.stock.mapper.MmsMedicineStockMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import static com.xyht.medicine_management_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.medicine_management_system.modules.stock.constant.StockFlag.STOCK_NORMAL;
import static com.xyht.medicine_management_system.modules.stock.constant.StockFlag.STOCK_SALE;
import static com.xyht.medicine_management_system.modules.stock.constant.StockType.STOCK_IN;
import static com.xyht.medicine_management_system.modules.stock.constant.StockType.STOCK_OUT;

/**
 * 新增 减少药品库存
 */
@Component
public class MedicineStockUtil {

    @Resource
    private MmsMedicineMapper medicineMapper;
    @Resource
    private MmsMedicineStockMapper medicineStockMapper;
    @Resource
    private MmsMedicineStockLogMapper medicineStockLogMapper;

    /**
     * 减少库存
     *
     * @param stockId        库存id
     * @param medicineId     药品id
     * @param reduceQuantity 减少的数量
     * @param userId         用户
     */
    @Transactional
    public void reduceMedicineStock(String stockId, String medicineId, Integer reduceQuantity, String userId) {

        if (isNullOrEmpty(stockId, medicineId, reduceQuantity)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        //校验药品
        MmsMedicine medicine = medicineMapper.selectById(medicineId);
        if (isNullOrEmpty(medicine)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_EXIST));
        }
        //校验库存
        MmsMedicineStock medicineStock = medicineStockMapper.selectById(stockId);
        if (isNullOrEmpty(medicineStock)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_NOT_EXIST));
        }
        //校验减少数量
        if (reduceQuantity < 0) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_NOT_NEGATIVE));
        }
        Integer stockQuantity = medicineStock.getStockQuantity();
        if (reduceQuantity > stockQuantity) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_REDUCE_OVER));
        }

        int sum = stockQuantity - reduceQuantity;
        medicineStock.setStockQuantity(sum);
        //减少库存数
        int result = medicineStockMapper.updateById(medicineStock);
        if (result != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_UPDATE_FAIL));
        }
        //减少入库存记录
        MmsMedicineStockLog medicineStockLog = new MmsMedicineStockLog();
        BeanUtils.copyProperties(medicineStock, medicineStockLog, "id");
        medicineStockLog.setMedicineName(medicine.getCommonNames());
        medicineStockLog.setMedicineCode(medicine.getMedicineCode());
        medicineStockLog.setMedicineId(medicineId);
        medicineStockLog.setStockId(stockId);
        medicineStockLog.setStockType(STOCK_OUT);
        medicineStockLog.setStockFlag(STOCK_NORMAL);
        medicineStockLog.setOutDate(new Date());
        medicineStockLog.setOutQuantity(reduceQuantity);
        medicineStockLog.setUserId(userId);
        int insertResult = medicineStockLogMapper.insert(medicineStockLog);
        if (insertResult != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_UPDATE_FAIL));
        }
    }

    /**
     * 减少库存
     *
     * @param medicineId     药品id
     * @param reduceQuantity 减少的库存量
     * @param userId         用户
     * @return 操作成功/失败
     */
    @Transactional
    public boolean reduceMedicineStock(String medicineId, Integer reduceQuantity, String userId) {
        if (isNullOrEmpty(medicineId, reduceQuantity, userId)) {
            return false;
        }
        //减少的库存量不可小于0
        if (reduceQuantity <= 0) {
            return false;
        }

        // 校验药品是否存在
        MmsMedicine medicine = medicineMapper.selectById(medicineId);
        if (isNullOrEmpty(medicine)) {
            return false;
        }

        // 校验库存
        List<MmsMedicineStock> medicineStockList = medicineStockMapper.selectList(new LambdaQueryWrapper<MmsMedicineStock>()
                .eq(MmsMedicineStock::getMedicineId, medicineId));
        if (medicineStockList.isEmpty()) {
            return false;
        }
        MmsMedicineStock medicineStock = medicineStockList.get(0);
        if (medicineStock.getStockQuantity() < reduceQuantity) {
            return false;
        }
        //当前库存 = 原库存 - 需要减少的库存
        int nowStockQuantity = medicineStock.getStockQuantity() - reduceQuantity;
        medicineStock.setStockQuantity(nowStockQuantity);
        int updNum = medicineStockMapper.updateById(medicineStock);
        if (updNum != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        //存入库存记录
        MmsMedicineStockLog medicineStockLog = new MmsMedicineStockLog();
        BeanUtils.copyProperties(medicineStock, medicineStockLog, "id");
        medicineStockLog.setMedicineName(medicine.getCommonNames());
        medicineStockLog.setMedicineCode(medicine.getMedicineCode());
        medicineStockLog.setMedicineId(medicineId);
        medicineStockLog.setStockId(medicineStock.getId());
        medicineStockLog.setStockType(STOCK_OUT);
        medicineStockLog.setStockFlag(STOCK_SALE);
        medicineStockLog.setOutDate(new Date());
        medicineStockLog.setOutQuantity(reduceQuantity);
        medicineStockLog.setUserId(userId);
        int insertNum = medicineStockLogMapper.insert(medicineStockLog);
        if (insertNum != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.FAIL));
        }

        return true;
    }

    /**
     * 增加库存
     *
     * @param stockId          库存id
     * @param medicineId       药品id
     * @param increaseQuantity 增加数量
     * @param userId           用户
     */
    @Transactional
    public void increaseMedicineStock(String stockId, String medicineId, Integer increaseQuantity, String userId) {
        if (isNullOrEmpty(stockId, medicineId, increaseQuantity)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.INVALID_PARAM));
        }

        MmsMedicine medicine = medicineMapper.selectById(medicineId);
        if (isNullOrEmpty(medicine)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_NOT_EXIST));
        }

        MmsMedicineStock medicineStock = medicineStockMapper.selectById(stockId);
        if (isNullOrEmpty(medicineStock)) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_NOT_EXIST));
        }

        if (increaseQuantity < 0) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_NOT_NEGATIVE));
        }
        int sum = medicineStock.getStockQuantity() + increaseQuantity;
        medicineStock.setStockQuantity(sum);
        //增加库存数
        int result = medicineStockMapper.updateById(medicineStock);
        if (result != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_UPDATE_FAIL));
        }

        //存入库存记录
        MmsMedicineStockLog medicineStockLog = new MmsMedicineStockLog();
        BeanUtils.copyProperties(medicineStock, medicineStockLog, "id");
        medicineStockLog.setMedicineId(medicineId);
        medicineStockLog.setMedicineName(medicine.getCommonNames());
        medicineStockLog.setMedicineCode(medicine.getMedicineCode());
        medicineStockLog.setStockId(stockId);
        medicineStockLog.setStockFlag(STOCK_NORMAL);
        medicineStockLog.setStockType(STOCK_IN);
        medicineStockLog.setIncomeDate(new Date());
        medicineStockLog.setIncomeQuantity(increaseQuantity);
        medicineStockLog.setUserId(userId);
        int insertResult = medicineStockLogMapper.insert(medicineStockLog);
        if (insertResult != 1) {
            ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.MEDICINE_STOCK_UPDATE_FAIL));
        }
    }

    /**
     * 获取药品库存
     *
     * @param medicineId 药品id
     * @return 药品库存
     */
    public Integer getMedicineStock(String medicineId) {
        List<MmsMedicineStock> medicineStockList = medicineStockMapper.selectList(new LambdaQueryWrapper<MmsMedicineStock>()
                .eq(MmsMedicineStock::getMedicineId, medicineId));
        if (medicineStockList.isEmpty()) {
            return 0;
        }

        return medicineStockList.get(0).getStockQuantity();
    }
}
